home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ETO Development Tools 4
/
ETO Development Tools 4.iso
/
Tools - Objects
/
MPW C++
/
MPW C++ PQR4
/
New Features in 3.2 C++
< prev
Wrap
Text File
|
1991-04-30
|
18KB
|
466 lines
Wednesday, April 17, 1991 5:04:35 PM
New features added to MPW C++ since 3.1 final: (This file describes
changes going backwards in time, with the most recent changes first.)
The only substantial feature we have promised for 3.2 alpha that is not in
this version is the AT&T CFront 2.1.0 merge. This CFront is based on
AT&T's 2.0 version.
----------------------------------------------
Changes in CFront 1.1d16 (a.k.a. CPlus 3.2d16)
Added code to remove dump files when CFront exits with an error status.
----------------------------------------------
Changes in CFront 1.1d16 (a.k.a. CPlus 3.2d16)
Fixed a "rehash failed" bug.
Changed constructor optimization (-z15) warnings to only come out with the
-w2 option.
----------------------------------------------
Changes in CFront 1.1d15 (a.k.a. CPlus 3.2d15)
In d13, any inline function that CFront "outlines" (most commonly a virtual
function whose body appears inside the class definition) causes CFront to
abort. D14 fixes this, but fixes it inadequately; d15, we hope, is right.
----------------------------------------------
Changes in CFront 1.1d13 (a.k.a. CPlus 3.2d13)
(d11 and d12 were buggy and did not go into wide distribution.) This
version implements "-model far" ("32-bit everything") properly and fixes a
MacApp bug.
WARNING: To use "-model far" you need to have new libraries and a new C
compiler:
1. You need the C compiler released for the ETO #3 disk or later. This
will be a C compiler with version "3.2b5q113experimental" or later. Earlier
C compilers simply do not support model far. (With model far, the C
compiler is doing most of the work. All CFront does differently is create
different method tables for Pascal objects.)
2. You need a new ObjLib.o in {Libraries} if you are building a MPW tool
(not an application) that has objects derived from PascalObject. The old
ObjLib.o does not support "model far" method dispatch.
3. You need a new MacApp library (MacApp 3.0; must support "qModelFar") if
you are using MacApp. (The reason is the same as above: the old MacApp
library only supports "model near" method dispatch.)
4. You need a new Runtime.o in {Libraries} if you are building just about
anything. (Technically, the old one will work if you have no global or
static objects that have constructors or destructors. The library code
that executes the constructors and destructors for global and static
objects breaks for "model far". Your program will get a bus-error when it
calls its destructors before terminating.) You need version "3.2b7exp2" or
later.
MacApp bug fixed: Consider the following code fragment:
class TParent : PascalObject {
virtual pascal void VFunc();
TParent *fParent;
};
pascal void TParent::VFunc()
{
fParent->VFunc();
fParent->TParent::VFunc();
}
According to the rules of C++, the first VFunc() call should use method
dispatch and the second one should not. (It will call TPARENT_VFUNC(), not
TPARENT$VFUNC().) CFront 1.1d10 and older versions would NOT use method
dispatch for either one. This would happen only when the function called
is the same as the one you are in -- i.e. you have what looks like
recursion (but actually isn't). In other contexts it would be correct. Now
it is correct in all cases.
This is a "MacApp bug" simply because it turned up in a MacApp 3.0 test
program and MacApp users would be more likely to see it than people who
don't use PascalObject a lot.
----------------------------------------------
Changes in CFront 1.1d10 (a.k.a. CPlus 3.2d10)
1.1d10 fixes a bug in which, if you have EXACTLY 256 virtual functions in a
class's virtual table, any class derived from that class will have its
virtual table misaligned. Also true of 512, 768 etc. -- any positive
number divisible by 256.
There is also a -z18 option that prints out some memory usage statistics.
I am not sure these will be of interest to anyone except the C++ team right
now. I am not entirely sure they are right. The numbers reported here will
not be the same numbers you see if you look at the memory usage window in
the Finder while CFront is running.
----------------------------------------------
Changes in CFront 1.1d9 (a.k.a. CPlus 3.2d9)
Bug fix: CFront generates C names for anonymous unions. (Usually they
look like "__C359" or "__O359".) In very large examples it would sometimes
leave these names out. It turned out to be misnumbering them because it
only allowed an unsigned char for anonymous union names -- when this
overflowed, it would mis-generate names. We have widened this field to a
short. (AT&T's code for 2.1.0 also has this field widened to a short.)
Unfortunately, this also means that dump files made with earlier compilers
will not be compatible with d9, and you will have to rebuild your dump
files.
Bug fix: 1.1d8 CFront generates expressions like this:
__F2?__dt__9TClassOneFv( __F2, 2) :(((void )0));
for lazy-evaluated destructor calls -- note the void cast on 0 so that both
legs of the conditional operator have void type. This cast was added
because earlier CFronts did not generate correct ANSI C code here. (ANSI C
requires that both legs be void if one is.) This fix introduced a new
problem, which we fixed in 1.1d9.
--------------------------------------------
Changes in CFront 1.1d8 (a.k.a. CPlus 3.2d8)
This is the first release that allows 32-bit PascalObjects. (This is the
-model far option.) It also fixes a code generation bug that did not
bother MPW C, but which was not correct ANSI C.
-model far
This option turns on 32-bit data and code references. By default ("model
near"), these references are a5-relative. "Model far" allows a larger
address space than the traditional Macintosh model.
If you do not have any classes derived from PascalObject, all CFront does
with "model far" is pass it along to the C compiler, and the C compiler
generates all the references differently.
If you have classes derived from PascalObject, CFront generates such
objects differently. The Pascal method tables are different for "model far"
and the objects are larger. Specifically, with "model near", each Pascal
object has a 2-byte field identifying what class it belongs to. With "model
far", this field is 4 bytes long. This means that the same class
declaration will yield objects of different sizes, with different offsets,
if it is compiled "model far" rather than "model near".
Therefore it is dangerous to link compilation units that have been compiled
with "model near" with compilation units compiled with "model far". If
both compilation units have code that manipulates objects of the same
Pascal object type, they will be incompatible, because the field offsets
will not match. The Linker will warn you if you make questionable mixes of
this kind. The solution is to either compile everything with the same
memory model, or at least collect all the code that manipulates a
particular Pascal object type and compile it with the same memory model.
Example: struct TThing : PascalObject { short a, b, c; }
would be 8 bytes long if compiled with "model near", 12 if compiled with
"model far". (That is, for "model near", 8 = 2 + 2 + 2 + 2, where the
first 2 identify the class at runtime. For "model far", 12 = 4 + 2 + 2 + 2
+ 2, where the first 4 identify the class and the last 2 pad the struct out
to a 4-byte boundary.)
1.1d8 generates "model bits" on function modules to warn the Linker that a
function uses fields of a PascalObject. However, current C compilers do
not support this, so this is turned off unless you use -z20. -z20 is not a
permanent option and will eventually become the default.
WARNING: DO NOT build code with "model far" PascalObjects if you do not
have a MacApp library that supports "model far" (in MacApp lingo,
"qModelFar") or at least an MPW ObjLib.o library that supports it. The
existing library code that supports Pascal method dispatches does not work
with "model far"! (The library functions that change are: %_METHOD,
%_NEWMETHOD, %_OBNEW and perhaps others.)
This warning goes for ALL applications built with MacApp, since all MacApp
objects are derived from TObject, and TObject is derived from PascalObject.
----------------------------------------------
Changes in CFront 1.1d7 (a.k.a. CPlus 3.2d7):
This release adds the -z15 and -z17 options, and refines the -z14 option
further.
-z17
CFront refuses to inline-expand functions greater than a certain size --
usually about 12 assignment statements is enough to cause an inline
function to be "outlined". -z17 turns this restriction off, so no matter
how large a function is, it will still be expanded inline.
We found it necessary to do this in order to get full value out of the -z15
optimizations. In deeply-nested object hierarchies that use multiple
inheritance, a constructor can easily exceed the built-in size limit. Such
a constructor will then be "outlined", which means that the optimization
cannot be done. The optimization will make it smaller, but because it is
done after the size is evaluated, that does not help.
If you have any doubts about whether this changes the number of
optimizations, compile the same thing with and without -z17 (using -z14 in
both cases) and count the number of optimization warnings.
Be careful with this: in some examples, some expressions are so deeply
nested that the C compiler cannot handle them. (This may happen anyway,
but happens more often if you use -z17.) If this causes trouble, either
don't use -z17 or else change the HEXA resource for the MPW Shell to allow
a bigger stack size. (This is described in the Release Notes for MPW C++
3.1.)
-z16
-z16 is reserved for debugging. It is not used in released compilers.
-z15
-z15 causes the -z14 optimizations to occur even for cases using multiple
inheritance. At this writing (September 1990) I am not satisfied that this
is a correct optimization for multiple inheritance. I have not been able
to construct a counterexample, but there might be one out there. Therefore
I wanted to flag -z15 as being more risky than -z14.
-z15 implies -z14. If you say both -z14 and -z15, that is the same as just
saying -z15.
[Postscript, February 1991. We are satisfied now that this is a correct
optimization for multiple inheritance. -z14 will be removed at some time
in the future and only -z15 -- which does both multiple and single
inheritance cases -- will be available.]
-z14 (changes)
This optimization has been extended so that it removes redundant vptr
initializations. See the description of -z14 below.
----------------------------------------------
Changes in CFront 1.1d6 (a.k.a. CPlus 3.2d6):
This release adds the -z14 and -z5 options.
-z14
-z14 causes some of the allocation code for nested inline constructors to
be optimized away. Suppose that you have two classes, "Base" and
"Derived", and "Base" has a constructor or a virtual function. (If it has
a virtual function, CFront will create a constructor for it if the user
does not make one. The purpose of this constructor is to set the vptr for
the object.) When a Derived object is created, its constructor will call
the Base constructor. When the calls for Derived::Derived() and
Base::Base() are expanded inline, some allocation code turns out to be
redundant. -z14 removes this code.
Because this is a new optimization, we recommend that you do not develop
code with -z14 on. Make sure your program works to your satisfaction
without -z14 first, and then try it again with -z14. If it stops working
properly, stop using -z14, and please notify us (AppleLink CPLUS.BUGS)
explaining the circumstances under which it does the wrong thing.
-z14 will issue a warning when it optimizes something. It may sometimes be
difficult to locate the code that corresponds to this warning in your
program, because when it occurs CFront is in the middle of an inline
expansion.
Here is a sample program you can try to see the difference in generated
code with and without -z14:
struct Base
{
virtual void f();
int Bfield;
};
struct Derived : public Base
{
void f();
int Dfield;
};
main()
{
Derived * p = new Derived;
}
Without -z14, the code generated to do the "new Derived" call will look
like this:
struct Derived *p;
struct Derived *__Xthis00b;
p = ((__Xthis00b = 0),
(( (__Xthis00b ||
(__Xthis00b = (struct Derived *) __nw__FUi(sizeof(struct Derived))))
?
( (__Xthis00b =
(struct Derived *)
(
(
(
(((struct Base *) __Xthis00b))
|| (__nw__FUi(sizeof(struct Base)))
)
? ((((struct Base *) __Xthis00b))->__vptr
= (struct __mptr *) __ptbl__4Base)
: 0
),
(((struct Base *) __Xthis00b))
)
),
(__Xthis00b->__vptr = (struct __mptr *) __ptbl__7Derived)
)
: 0),
__Xthis00b)
);
With -z14, it looks like this:
struct Derived *p;
struct Derived *__Xthis00b;
p = ((__Xthis00b = 0),
(( (__Xthis00b ||
(__Xthis00b = (struct Derived *) __nw__FUi(sizeof(struct Derived))))
?
( (__Xthis00b =
(struct Derived *)
(
(0),
(((struct Base *) __Xthis00b))
)
),
(__Xthis00b->__vptr = (struct __mptr *) __ptbl__7Derived)
)
: 0),
__Xthis00b)
);
The inner test of __Xthis00b and the call to __nw__FUi(sizeof(struct Base))
have been removed. They are not necessary because in the outer context
__Xthis00b has already been tested and __nw__FUi(sizeof(struct Derived))
has already been used to initialize it.
The first vptr initialization has also been removed, because it gets done
again afterwards. This part of the optimization would not be done if Base
had a non-empty user-defined constructor. (Note that here what you are
actually getting is an inline-expanded compiler-generated constructor for
Base and Derived. You can see these plainly if you compile with -z0, which
turns off all inlining.)
(The optimization to remove the vptr initialization was added in 3.2d7; the
rest of it was done in 3.2d6.)
Some of this code, e.g. the (0) expression, is just useless nonsense. The
MPW C compiler will not generate any code for this.
This particular example, when run through the MPW C 3.2b1 compiler, has
main() being 122 bytes long in the unoptimized version and 78 bytes long in
the optimized version. Therefore using -z14 saved 44 bytes of code here.
This optimization can only be done where constructors are inline-expanded.
It takes advantage of the code that appears when one constructor is
inline-expanded within another.
This optimization does not occur for objects derived from PascalObject.
Such objects use Pascal method tables instead of C++ vtables and the
allocation code is completely different.
This optimization DOES occur for objects derived from HandleObject or
SingleObject.
The compiler will issue a warning where these optimizations occur.
Areas where -z14 may cause trouble:
(1) If you assign to "this" in your constructors, -z14 may do an incorrect
optimization. I have not been able to create a test case in which this
occurs, but I suspect it may happen.
(2) If you overload operator "new", either globally or locally, and have it
do something other than allocation (e.g. it has interesting side effects,
printfs() or whatever), the -z14 code may not be what you expect. I have
not been able to create a test case in which this occurs, but I suspect it
may happen.
This optimization will not be done where multiple inheritance is used. It
only occurs with classes that only have one base class. (You do not have
to derive from SingleObject to get this optimization, though.) If you want
this also to be done with multiple inheritance, use -z15 instead. (See
the section on 3.2d7 above. -z15 does not exist in 3.2d6.)
To get full value out of this optimization, try the -z17 option at the same
time, which will keep some of the larger constructors from being
"outlined". (See the section on 3.2d7 above. -z17 does not exist in
3.2d6.)
-z5
-z5 stops the linker from stripping static objects that are never used, but
that have constructors or destructors. According to Bjarne Stroustrup,
these constructors and destructors must be run for their side effects. The
default behavior at Apple is to strip them, and that is what most users are
accustomed to, so we made this an option.
C++ code ported to MPW C++ from some other environment should be compiled
with -z5, because it's likely that the people who developed that code
assumed all static object constructors and destructors would be executed.
---------------------------------------------
Changes in CFront 1.1d5 (a.k.a. CPlus 3.2d5):
CFront 1.1d5 was essentially the same thing as C++ 3.1 final (CFront 1.0).
1.1d5 was made BEFORE 3.1 final and its changes were rolled into 3.1 final.
There are some cosmetic differences -- that's all. (For example, the
Commando resource should list -opt as one of the options passed to the C
compiler. This is not mentioned in 3.1 final because the MPW 3.1 C
compiler does not allow -opt. It's a hidden option in 3.1 final.)
There were NEVER any releases 1.1d1-1.1d4. We skipped those numbers in
order to avoid confusion with the 3.1 (CFront 1.0) beta release numbers
(3.1b1, b2, b3, b4).
Things expected, but not yet done:
3.2 C++ will have AT&T CFront 2.1.0 rolled into it. This is a bug-fix
release from AT&T and has no new features. We haven't put it in yet.
Bugs to CPLUS.BUGS on AppleLink, or Mark Bjerke on QuickMail.
Questions about this document to me (Preston Gardner).
The C++ team is:
Harvey Alcabes (Product Marketing)
Mark Bjerke (Development Systems Group)
Preston Gardner (Development Systems Group)